﻿#pragma once

#include <learn/geom/geom_nonbasis.h>

namespace xi
{

namespace geom
{

template <std::size_t N> struct Geom_TrimmedCurve : public Geom_NonbasisCurve<N>
{
    using Vec = VecT<N, double>;

  public:
    /**
     * @brief 裁剪曲线
     *
     * @param[in] curve
     * @param[in] t0
     * @param[in] t1
     */
    Geom_TrimmedCurve(std::shared_ptr<Geom_Curve<N>> curve, double t0, double t1)
        : m_curve(curve), m_first(t0), m_last(t1)
    {
    }

    /**
     * @brief 获得完整曲线
     *
     * @return std::shared_ptr<Geom_Curve<N>>
     */
    std::shared_ptr<Geom_Curve<N>> curve() const
    {
        return m_curve;
    }

    /**
     * @brief 计算曲线上点的位置
     *
     * @param[in] t
     * @return Vec
     */
    Vec d0(double t) const override
    {
        return m_curve->d0(t);
    }

    /**
     * @brief 计算曲线上点的位置和导数
     *
     * @param[in] t
     * @return std::array<Vec, 2>
     */
    std::array<Vec, 2> d1(double t) const override
    {
        return m_curve->d1(t);
    }

    /**
     * @brief 计算曲线上点的位置、导数和二阶导数
     *
     * @param[in] t
     * @return std::array<Vec, 3>
     */
    std::array<Vec, 3> d2(double t) const override
    {
        return m_curve->d2(t);
    }

    /**
     * @brief 计算曲线上点的位置、导数、二阶导数和三阶导数
     *
     * @param[in] t
     * @return std::array<Vec, 4>
     */
    std::array<Vec, 4> d3(double t) const override
    {
        return m_curve->d3(t);
    }

    /**
     * @brief 起始参数
     *
     * @return double
     */
    double first_param() const override
    {
        return m_first;
    }

    /**
     * @brief 终止参数
     *
     * @return double
     */
    double last_param() const override
    {
        return m_last;
    }

    /**
     * @brief 序列化
     *
     * @return utils::Json
     */
    utils::Json dump_json() const override
    {
        utils::Json json;
        json["type"] = "param_curve";
        json["first_param"] = m_first;
        json["last_param"] = m_last;
        return json;
    }

  protected:
    std::shared_ptr<Geom_Curve<N>> m_curve;
    double m_first, m_last;
};

} // namespace geom

} // namespace xi